package com.such.kit.io.template;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.such.kit.io.bean.TextIOConfig;
import com.such.kit.io.simple.TextIOSimple;
import com.such.kit.io.source.DatabaseIOSource;
import com.such.kit.io.support.IOSource;
import com.such.kit.io.template.support.IOTemplate;
import com.such.kit.stream.StreamCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @author SUCH
 * <pre>
 * [继承扩展于 {@link IOTemplate}] 的文本类型 IO 工具类
 * TextIOTemplate 通过 {@link IOTemplate#templateIn 模板} {@link #initTemplate() 初始化} 构建 {@link TextIOConfig}
 * 内部实现基于 {@link TextIOSimple} 完成
 * 
 * TextIOTemplate 的模板介质为文本文件
 * TextIOTemplate 的模板格式应符合 JSON 标准
 * 
 * [举例] 以 {@link DatabaseIOSource} 为类
 * JSON
 * {
 *   {@link TextIOConfig#fileType IO_FILE_TYPE}: "csv", 
 *   {@link TextIOConfig#charset IO_CHARSET}: "UTF-8", 
 *   {@link TextIOConfig#mode IO_MODE}: "separate", 
 *   {@link TextIOConfig#modeParam IO_MODE_PARAM}: {separator: ",", qualifier: "\""}, 
 *   {@link TextIOConfig#ignoreRow IO_IGNORE_ROW}: 1, 
 *   {@link TextIOConfig#titleTemplate IO_TITLE_TEMPLATE}: ["用户名", "表名", "表说明"], 
 *   {@link TextIOConfig#dataTemplate IO_DATA_TEMPLATE}: "\"#[schema]\", \"#[tableName]\", \"#[tableComment]\"", 
 *   {@link TextIOConfig#rowQualifier IO_ROW_QUALIFIER}: "\r", 
 *   {@link TextIOConfig#inputExpression IO_INPUT_EXPRESSION}: ["insert into TABLE_INFO (schema, name, comment) value (:schema, :tableName, :tableComment)"], 
 *   {@link TextIOConfig#outputExpression IO_OUTPUT_EXPRESSION}: "select schema as schema, name as tableName, comment as tableComment from TABLE_INFO"
 * }
 * 数据
 * "用户名", "表名", "表说明"
 * "IO", "TABLE1", "TABLE1 COMMENT"
 * "IO", "TABLE2", "TABLE2 COMMENT"
 * "IO", "TABLE3", "TABLE3 COMMENT"
 * 
 * [保留字] 列表
 *   {@link TextIOSimple#RESERVED_WORD_ROW_NUMBER}
 * </pre>
 */
public class TextIOTemplate extends IOTemplate {

	private TextIOSimple ioSimple;

	/** [参考 {@link IOTemplate#IOTemplate(String)}] */
	public TextIOTemplate(String templatePath) throws Exception {
		super(templatePath);
	}

	/** [参考 {@link IOTemplate#IOTemplate(String, String, IOSource)}] */
	public TextIOTemplate(String templateString, String charset) throws Exception {
		super(templateString, charset);
	}

	/** [参考 {@link IOTemplate#IOTemplate(byte[], IOSource)}] */
	public TextIOTemplate(byte[] templateBytes) throws Exception {
		super(templateBytes);
	}

	/** [参考 {@link IOTemplate#IOTemplate(InputStream, IOSource)}] */
	public TextIOTemplate(InputStream templateIn) throws Exception {
		super(templateIn);
	}

	@Override
	protected void initTemplate() throws Exception {
		if (ValidateCommons.isEmpty(this.ioSimple)) {
			try {
				String configJson = StreamCommons.textReader(new InputStreamReader(super.templateIn));
				TextIOConfig config = JSON.parseObject(configJson, TextIOConfig.class);
				this.ioSimple = new TextIOSimple(config);
			} finally {
				StreamCommons.close(super.templateIn);
			}
		}
	}

	@Override
	public void setCharset(String charset) {
		this.ioSimple.setCharset(charset);
	}

	@Override
	public void putArg(String key, Object value) {
		this.ioSimple.putArg(key, value);
	}

	@Override
	public void putArgs(Map<String, Object> args) {
		this.ioSimple.putArgs(args);
	}

	@Override
	public void clearArgs() {
		this.ioSimple.clearArgs();
	}

	@Override
	public String getFileType() {
		return this.ioSimple.getFileType();
	}

	@Override
	public void input(IOSource ioSource, InputStream resourceIn) throws Exception {
		this.ioSimple.input(ioSource, resourceIn);
	}

	@Override
	public void output(IOSource ioSource, OutputStream resourceOut) throws Exception {
		this.ioSimple.output(ioSource, resourceOut);
	}

}
